/*************************************************************************
    > File Name    : ThreadPool.cc
    > Author       : LiuLei
    > Mail         : 2261459486@qq.com 
    > Created Time : 2022年11月24日 星期四 22时15分14秒
 ************************************************************************/

#include "../../include/server/ThreadPool.h"
#include <unistd.h>

ThreadPool::ThreadPool(size_t threadNumber, size_t queueSize)
: _threadNumber(threadNumber)
, _threads()
, _queueSize(queueSize)
, _taskQueue(_queueSize)
, _isExitTP(false)
{
    _threads.reserve(_threadNumber);
}

ThreadPool::~ThreadPool()
{
    if(_isExitTP)
    {
        this->stop();
        _isExitTP = false;
    }
}

void ThreadPool::start()
{
    //子线程放入容器
    for(size_t idx = 0; idx != _threadNumber; ++idx)
    {
        unique_ptr<Thread> up
            (new Thread(std::bind(&ThreadPool::threadFunc, this), idx + 1));
        _threads.push_back(std::move(up));

        //子线程启动
        _threads.back()->start();
    }
}

void ThreadPool::stop()
{
    //等待_taskQueue空
    while(!_taskQueue.empty())
    {
        ::sleep(1);
    }

    _isExitTP = true;
    _taskQueue.weakup();

    //子线程停止
    for(auto &th : _threads)
    {
        th->stop();
    }
}

void ThreadPool::addTask(const Task &task)
{
    if(task)
    {
        _taskQueue.push(std::move(task));
    }
}

void ThreadPool::addTask(Task &&task)
{
    if(task)
    {
        _taskQueue.push(std::move(task));
    }
}

Task ThreadPool::getTask()
{
    return _taskQueue.pop();
}

void ThreadPool::threadFunc()
{
    //循环获取任务并执行
    while(!_isExitTP)
    {
        Task taskcb = getTask();
        if(taskcb)
        {
            taskcb();
        }
    }
}
